-- -------------------------------------------------------------------------
-- Features/Setting.lua
-- Settings & Theme Management
-- -------------------------------------------------------------------------

local module = {}

-- [Dependencies]
local ui = nil
local config = nil
local lang = nil
local debugger = nil
local features_config = nil
local player_info = nil
local input_module = nil

-- [Lua 5.4] <const> for function references
local table_insert <const> = table.insert
local ipairs <const> = ipairs
local os_clock <const> = os.clock
local math_floor <const> = math.floor

-- [Translation Helper]
local function _T(text)
    if _G and _G._T then
        return _G._T(text)
    end
    if lang then
        if lang.get then return lang.get(text) end
        if lang.get_text then return lang.get_text(text) end
    end
    return text
end

-- [Helper Functions]
local function update_if_changed(target_table, key, new_value)
    if target_table[key] ~= new_value then
        target_table[key] = new_value
    end
end

-- -------------------------------------------------------------------------
-- Configuration Constants
-- -------------------------------------------------------------------------

local SAVE_COOLDOWN <const> = 1.0

-- [State]
local state = {
    subtab_idx = 1,
    layout_subtab_idx = 1,
    theme_subtab_idx = 1,
    icons_subtab_idx = 1,
    notify_subtab_idx = 1,
    color_keys_window = nil,
    color_keys_group = nil,
    color_keys_text = nil,
    color_keys_tab = nil,
    color_keys_subtab = nil,
    color_keys_controls = nil,
    color_keys_slider = nil,
    color_keys_combo = nil,
    color_keys_scrollbar = nil,
    color_keys_inline = nil,
    color_keys_progress = nil,
    color_keys_menu_hints = nil,
    color_keys_tags = nil,
    color_keys_overlay = nil,
    color_keys_notify_left = nil,
    color_keys_notify_right = nil,
    last_save_time = 0,
    save_cooldown = SAVE_COOLDOWN,
    bg_images = {_T("None")},
    bg_idx = 1,
    images_cached = false,
    available_themes = {"Default"},
    themes_cached = false,
    current_theme_idx = 1,
    new_theme_name = ""
}

local function show_toast(text, type_str)
    if ui and ui.notify then
        ui.notify(text, type_str or "Info")
    elseif util and util.toast then
        util.toast(text)
    end
end

local function sync_debug_settings(force)
    local debug_sys = _G.debug_sys
    if not debug_sys then return end

    local cfg = debug_sys.get_config()
    if not cfg then return end

    if not features_config then return end

    local debug_cfg = {
        enabled = cfg.enabled,
        log_level = cfg.log_level,
        show_timestamp = cfg.show_timestamp,
        show_memory = cfg.show_memory,
        show_performance = cfg.show_performance,
        log_to_file = cfg.log_to_file,
        print_to_console = cfg.print_to_console,
        module_filter = cfg.module_filter
    }

    features_config.set_debug_config(debug_cfg)

    local now = os_clock()
    if force or (now - state.last_save_time >= state.save_cooldown) then
        features_config.force_save()
        state.last_save_time = now
    end
end

local function rebuild_color_cache()
    if not config or not config.data or not config.data.colors then return end

    local categories = {
        window = {
            "Window Background", "Sidebar Background", "Header Background",
            "Header Text", "Background Tint"
        },
        group = {
            "Group Background", "Group Header Text", "Group Header Line",
            "Widget Background", "Widget Hover"
        },
        text = {
            "Text Primary", "Text Secondary", "Accent"
        },
        tab = {
            "Tab Background", "Tab Background Hover", "Tab Background Active",
            "Tab Text Inactive", "Tab Text Active", "Tab Indicator"
        },
        subtab = {
            "Subtab Background", "Subtab Hover", "Subtab Active",
            "Subtab Text Inactive", "Subtab Text Active"
        },
        controls = {
            "Checkbox Active", "Checkbox Inactive",
            "Toggle Active", "Toggle Inactive", "Knob Active", "Knob Inactive"
        },
        slider = {
            "Slider Background", "Slider Background Hover",
            "Slider Empty", "Slider Filled", "Slider Filled Hover"
        },
        combo = {
            "Combo Background", "Combo Highlight", "Player Selected Background"
        },
        scrollbar = {
            "Scrollbar", "Scrollbar Hover"
        },
        inline = {
            "Inline Tab Active", "Inline Tab Inactive", "Inline Tab Indicator",
            "Separator Line", "Separator Text"
        },
        progress = {
            "Progress Background", "Progress Fill"
        },
        menu_hints = {
            "Menu Hints Background", "Menu Hints Text"
        },
        tags = {
            "Tag ME", "Tag Friend", "Tag Modder", "Tag God",
            "Tag Spectating", "Tag Modded", "Tag Bounty",
            "Tag Script Host", "Tag Session Host", "Tag Vehicle",
            "Tag Next Host", "Tag CEO", "Tag Dead", "Tag Interior", "Tag Controller"
        },
        overlay = {
            "Overlay Background", "Overlay Text", "Overlay Divider"
        },
        notify_left = {
            "Notification Background", "Notification Join", "Notification Leave"
        },
        notify_right = {
            "Notification Success", "Notification Warning", "Notification Error"
        }
    }

    local function filter_existing(keys)
        local result = {}
        for _, key in ipairs(keys) do
            if config.data.colors[key] then
                table_insert(result, key)
            end
        end
        return result
    end

    state.color_keys_window = filter_existing(categories.window)
    state.color_keys_group = filter_existing(categories.group)
    state.color_keys_text = filter_existing(categories.text)
    state.color_keys_tab = filter_existing(categories.tab)
    state.color_keys_subtab = filter_existing(categories.subtab)
    state.color_keys_controls = filter_existing(categories.controls)
    state.color_keys_slider = filter_existing(categories.slider)
    state.color_keys_combo = filter_existing(categories.combo)
    state.color_keys_scrollbar = filter_existing(categories.scrollbar)
    state.color_keys_inline = filter_existing(categories.inline)
    state.color_keys_progress = filter_existing(categories.progress)
    state.color_keys_menu_hints = filter_existing(categories.menu_hints)
    state.color_keys_tags = filter_existing(categories.tags)
    state.color_keys_overlay = filter_existing(categories.overlay)
    state.color_keys_notify_left = filter_existing(categories.notify_left)
    state.color_keys_notify_right = filter_existing(categories.notify_right)
end

local function get_clickui_dir()
    if config and config.get_base_dir then
        return config.get_base_dir()
    end
    local base = tostring((paths and paths.script) or ".\\")
    if not base:match("[\\/]$") then base = base .. "\\" end
    if not base:lower():match("clickul[\\/]$") then
        base = base .. "ClickUl\\"
    end
    return base
end

local function refresh_theme_list(force)
    if state.themes_cached and not force then
        return
    end

    if config and config.list_themes then
        local ok, themes = pcall(config.list_themes)
        if ok and themes then
            state.available_themes = themes

            local current_name = "Default"
            if config.get_current_theme_name then
                local ok2, name = pcall(config.get_current_theme_name)
                if ok2 and name then current_name = name end
            end

            state.current_theme_idx = 1
            for i, theme_name in ipairs(state.available_themes) do
                if theme_name == current_name then
                    state.current_theme_idx = i
                    break
                end
            end
        end
    end

    state.themes_cached = true
end

local function cleanup_deprecated_settings()
    if not config or not config.data then return end

    local cleaned = false

    if config.data.base and config.data.base.notif_slide_offset ~= nil then
        config.data.base.notif_slide_offset = nil
        cleaned = true
        if debugger then
            debugger.info("[Setting] Removed deprecated setting: notif_slide_offset")
        end
    end

    if config.data.base and config.data.base.font_notif ~= nil then
        config.data.base.font_notif = nil
        cleaned = true
        if debugger then
            debugger.info("[Setting] Removed deprecated setting: font_notif")
        end
    end

    if config.data.base and config.data.base.text_y_offset ~= nil then
        config.data.base.text_y_offset = nil
        cleaned = true
        if debugger then
            debugger.info("[Setting] Removed deprecated setting: text_y_offset")
        end
    end

    if config.data.debug ~= nil then
        config.data.debug = nil
        cleaned = true
        if debugger then
            debugger.info("[Setting] Removed deprecated config: debug (migrated to features_config)")
        end
    end

    if cleaned and config.save then
        pcall(config.save)
    end
end

local function refresh_image_list(force)
    if state.images_cached and not force then
        return
    end

    state.bg_images = {_T("None")}

    if not dirs or not dirs.list then return end

    local img_path = get_clickui_dir() .. "Images\\"

    if dirs.create then
        local ok, err = pcall(dirs.create, img_path)
        if not ok and debugger then
            debugger.warn("[Setting] Failed to create Images directory", {error = err})
        end
    end

    local ok, files = pcall(dirs.list, img_path, "png")
    if ok and files then
        for _, f in ipairs(files) do
            local name = f:match("([^\\]+)$") or f
            table_insert(state.bg_images, name)
        end
    elseif not ok and debugger then
        debugger.debug("[Setting] Could not list PNG files", {error = files})
    end

    local ok_jpg, jpgs = pcall(dirs.list, img_path, "jpg")
    if ok_jpg and jpgs then
        for _, f in ipairs(jpgs) do
            local name = f:match("([^\\]+)$") or f
            table_insert(state.bg_images, name)
        end
    elseif not ok_jpg and debugger then
        debugger.debug("[Setting] Could not list JPG files", {error = jpgs})
    end

    local ok_gif, gifs = pcall(dirs.list, img_path, "gif")
    if ok_gif and gifs then
        for _, f in ipairs(gifs) do
            local name = f:match("([^\\]+)$") or f
            table_insert(state.bg_images, name)
        end
    elseif not ok_gif and debugger then
        debugger.debug("[Setting] Could not list GIF files", {error = gifs})
    end

    local current = config.data.bg_image_file
    state.bg_idx = 1
    if current and current ~= "" then
        for i, name in ipairs(state.bg_images) do
            if name == current then
                state.bg_idx = i
                break
            end
        end
    end

    state.images_cached = true
end

-- -------------------------------------------------------------------------
-- Module Interface
-- -------------------------------------------------------------------------

function module.init(ui_lib, cfg_lib, _, lang_lib, _, _, debug_lib)
    ui = ui_lib
    config = cfg_lib
    lang = lang_lib
    debugger = debug_lib

    assert(ui, "[Setting] UI library is required")
    assert(config, "[Setting] Config library is required")

    local ok, fc = pcall(require, "ClickUl.Config.features")
    if ok and fc then
        features_config = fc
    end

    local ok_pi, pi = pcall(require, "ClickUl.Features.PlayerInfo")
    if ok_pi and pi then
        player_info = pi
    end

    local ok_inp, inp_mod = pcall(require, "ClickUl.UI.input")
    if ok_inp then
        input_module = inp_mod
    end

    if config and config.data and config.data.debug and features_config then
        local old_debug = config.data.debug
        if not features_config.has_debug_config() then
            features_config.set_debug_config(old_debug)
            features_config.force_save()
            if debugger then
                debugger.info("[Setting] Migrated debug config from theme to features")
            end
        end
        config.data.debug = nil
        if config.save then
            pcall(config.save)
        end
    end

    cleanup_deprecated_settings()

    if debugger then
        debugger.info("[Setting] Module initialized successfully")
    end

    rebuild_color_cache()

    if not config.data.sidebar_icons then
        config.data.sidebar_icons = {}
    end
    refresh_image_list()
    refresh_theme_list()

    sync_debug_settings()

    return true
end

function module.on_menu_open()
    if not state.color_keys_window then
        rebuild_color_cache()
    end
end

function module.on_menu_close()
    sync_debug_settings(true)
end

function module.draw()
    state.subtab_idx = ui.SubTabBar({
        _T("General"),
        _T("Layout"),
        _T("Theme"),
        _T("Icons"),
        _T("Notify"),
        _T("Player Info"),
        _T("Debug")
    }, state.subtab_idx or 1)

    if state.subtab_idx == 1 then
        ui.DualColumn(
            function()
                ui.Group(_T("Features Config"), function()
                    if features_config then
                        local enabled = features_config.is_enabled()
                        local new_enabled = ui.Checkbox(_T("Auto Save Features"), enabled)
                        if new_enabled ~= enabled then
                            features_config.set_enabled(new_enabled)
                            if new_enabled then
                                show_toast(_T("Auto save enabled"), "Success")
                            else
                                show_toast(_T("Auto save disabled"), "Info")
                            end
                        end

                        if ui.Button(_T("Save Now")) then
                            if features_config.force_save() then
                                show_toast(_T("Features config saved"), "Success")
                            else
                                show_toast(_T("Save failed"), "Error")
                            end
                        end

                        if ui.Button(_T("Reset Features Config")) then
                            features_config.reset()
                            show_toast(_T("Features config reset"), "Warning")
                        end
                    else
                        ui.Button(_T("Features Config Unavailable"))
                    end
                end)

                ui.Group(_T("Language"), function()
                    local current_idx = (lang and lang.get_lang_index) and lang.get_lang_index() or 1
                    local lang_list = (lang and lang.get_lang_list) and lang.get_lang_list() or {"en"}

                    local new_lang_idx = ui.Combo(_T("Language"), current_idx, lang_list)
                    if new_lang_idx ~= current_idx then
                        local ok, result = false, false
                        if lang and lang.set_lang_by_index then
                            ok, result = pcall(lang.set_lang_by_index, new_lang_idx)
                        end
                        if ok and result then
                            if ui.toggle_menu then
                                ui.toggle_menu()
                            end
                            show_toast(_T("Language changed"), "Success")
                        else
                            show_toast(_T("Failed to load language"), "Error")
                        end
                    end

                    if ui.Button(_T("Refresh Language")) then
                        if lang and lang.refresh_available then
                            pcall(lang.refresh_available)
                        end
                        local ok, result = false, false
                        if lang and lang.reload then
                            ok, result = pcall(lang.reload)
                        end
                        if ok and result then
                            show_toast(_T("Language Reloaded"), "Success")
                        else
                            show_toast(_T("Failed to reload language"), "Error")
                        end
                    end
                end)
            end,
            function()
                ui.Group(_T("Input"), function()
                    if ui.get_block_input then
                        local blocked = ui.Checkbox(_T("Block Input"), ui.get_block_input())
                        ui.set_block_input(blocked)
                    end
                end)

                ui.Group(_T("UI Style"), function()
                    local old_style = config.data.base.checkbox_use_toggle_style or false
                    local new_style = ui.Toggle(
                        _T("Checkbox Toggle Style"),
                        old_style
                    )
                    if new_style ~= old_style then
                        config.data.base.checkbox_use_toggle_style = new_style
                        config.data.current.checkbox_use_toggle_style = new_style
                        if config.save then
                            pcall(config.save)
                        end
                    end
                end)
            end
        )

    elseif state.subtab_idx == 2 then
        state.layout_subtab_idx = ui.SubTabBar2({
            _T("Interface Parameters"),
            _T("Advanced Options")
        }, state.layout_subtab_idx or 1)

        if state.layout_subtab_idx == 1 then
            ui.DualColumn(
                function()
                    ui.Group(_T("Interface Layout"), function()
                        update_if_changed(config.data.base, "w", ui.Slider(_T("Menu Width"), config.data.base.w, 500, 1000, 10))
                        update_if_changed(config.data.base, "h", ui.Slider(_T("Menu Height"), config.data.base.h, 300, 1080, 10))
                        update_if_changed(config.data.base, "header_h", ui.Slider(_T("Header Height") .. "##menu", config.data.base.header_h, 20, 100, 1))
                        update_if_changed(config.data.base, "sidebar_w", ui.Slider(_T("Sidebar Width"), config.data.base.sidebar_w, 40, 150, 1))
                        update_if_changed(config.data.base, "padding", ui.Slider(_T("Padding"), config.data.base.padding or 20, 5, 40, 1))
                        update_if_changed(config.data.base, "item_h", ui.Slider(_T("Item Height"), config.data.base.item_h or 40, 24, 60, 1))
                        update_if_changed(config.data.base, "button_h", ui.Slider(_T("Button Height"), config.data.base.button_h or 40, 24, 60, 1))
                        update_if_changed(config.data.base, "slider_h", ui.Slider(_T("Slider Height"), config.data.base.slider_h or 60, 40, 80, 1))
                        update_if_changed(config.data.base, "item_spacing", ui.Slider(_T("Item Spacing"), config.data.base.item_spacing or 8, 2, 20, 1))
                    end)

                    ui.Group(_T("Corner Rounding"), function()
                        local old_rounding = config.data.base.window_rounding or 8
                        local rounding = ui.Slider(_T("Window Rounding"), old_rounding, 0, 30, 1)
                        if rounding ~= old_rounding then
                            config.data.base.window_rounding = rounding
                            config.data.base.window_rounding_tl = rounding
                            config.data.base.window_rounding_tr = rounding
                            config.data.base.window_rounding_bl = rounding
                            config.data.base.window_rounding_br = rounding
                            config.data.base.header_rounding_tl = rounding
                            config.data.base.header_rounding_tr = rounding
                        end
                    end)

                    ui.Group(_T("Sidebar"), function()
                        update_if_changed(config.data.base, "sidebar_btn_margin", ui.Slider(_T("Button Margin"), config.data.base.sidebar_btn_margin or 6, 2, 16, 1))
                        update_if_changed(config.data.base, "sidebar_icon_size", ui.Slider(_T("Icon Size"), config.data.base.sidebar_icon_size or 32, 16, 48, 1))
                        update_if_changed(config.data.base, "sidebar_btn_spacing", ui.Slider(_T("Button Spacing"), config.data.base.sidebar_btn_spacing or 4, 0, 12, 1))
                        update_if_changed(config.data.base, "sidebar_btn_rounding", ui.Slider(_T("Button Rounding"), config.data.base.sidebar_btn_rounding or 6, 0, 20, 1))
                    end)

                    ui.Group(_T("SubTab Bar"), function()
                        update_if_changed(config.data.base, "subtab_height", ui.Slider(_T("Height") .. "##subtab", config.data.base.subtab_height or 30, 20, 50, 1))
                        update_if_changed(config.data.base, "subtab_gap", ui.Slider(_T("Gap") .. "##subtab", config.data.base.subtab_gap or 8, 2, 20, 1))
                        update_if_changed(config.data.base, "subtab_rounding", ui.Slider(_T("Rounding") .. "##subtab", config.data.base.subtab_rounding or 6, 0, 20, 1))
                        update_if_changed(config.data.base, "subtab_spacing_after", ui.Slider(_T("Spacing After"), config.data.base.subtab_spacing_after or 6, 0, 30, 1))
                    end)
                end,
                function()
                    ui.Group(_T("Font Sizes"), function()
                        update_if_changed(config.data.base, "font_header", ui.Slider(_T("Header Font"), config.data.base.font_header, 14, 32, 1))
                        update_if_changed(config.data.base, "font_tab", ui.Slider(_T("Tab Font"), config.data.base.font_tab or 15, 14, 32, 1))
                        update_if_changed(config.data.base, "font_subtab", ui.Slider(_T("SubTab Font"), config.data.base.font_subtab or 13, 10, 24, 1))
                        update_if_changed(config.data.base, "font_group", ui.Slider(_T("Group Font"), config.data.base.font_group, 10, 24, 1))
                        update_if_changed(config.data.base, "font_widget", ui.Slider(_T("Widget Font"), config.data.base.font_widget, 10, 24, 1))
                        update_if_changed(config.data.base, "font_small", ui.Slider(_T("Small Text Font"), config.data.base.font_small, 8, 20, 1))
                    end)

                    ui.Group(_T("Group Settings"), function()
                        update_if_changed(config.data.base, "group_header_height", ui.Slider(_T("Header Height") .. "##group", config.data.base.group_header_height or 36, 24, 60, 1))
                        update_if_changed(config.data.base, "group_content_padding", ui.Slider(_T("Content Padding"), config.data.base.group_content_padding or 10, 4, 24, 1))
                        update_if_changed(config.data.base, "group_spacing", ui.Slider(_T("Spacing"), config.data.base.group_spacing or 8, 4, 32, 1))
                        update_if_changed(config.data.base, "group_rounding", ui.Slider(_T("Rounding") .. "##group", config.data.base.group_rounding or 8, 0, 20, 1))
                    end)

                    ui.Group(_T("Widget General"), function()
                        update_if_changed(config.data.base, "widget_rounding", ui.Slider(_T("Rounding") .. "##widget", config.data.base.widget_rounding or 6, 0, 16, 1))
                        update_if_changed(config.data.base, "widget_text_padding", ui.Slider(_T("Text Padding"), config.data.base.widget_text_padding or 10, 4, 24, 1))
                    end)
                end
            )

        elseif state.layout_subtab_idx == 2 then
            ui.DualColumn(
                function()
                    ui.Group(_T("Slider Settings"), function()
                        update_if_changed(config.data.base, "slider_height", ui.Slider(_T("Thickness"), config.data.base.slider_height, 2, 12, 1))
                        update_if_changed(config.data.base, "slider_track_offset", ui.Slider(_T("Vertical Offset"), config.data.base.slider_track_offset, 20, 50, 1))
                        update_if_changed(config.data.base, "slider_extra_height", ui.Slider(_T("Extra Height"), config.data.base.slider_extra_height or 20, 10, 40, 1))
                    end)

                    ui.Group(_T("Scrollbar"), function()
                        update_if_changed(config.data.base, "scrollbar_width", ui.Slider(_T("Scrollbar Width"), config.data.base.scrollbar_width, 2, 20, 1))
                        update_if_changed(config.data.base, "scrollbar_thumb_min", ui.Slider(_T("Thumb Min Size") .. "##scrollbar", config.data.base.scrollbar_thumb_min or 20, 10, 50, 1))
                        update_if_changed(config.data.base, "scrollbar_hit_width", ui.Slider(_T("Hit Width"), config.data.base.scrollbar_hit_width or 16, 8, 30, 1))
                    end)

                    ui.Group(_T("Checkbox"), function()
                        update_if_changed(config.data.base, "checkbox_width", ui.Slider(_T("Width"), config.data.base.checkbox_width or 40, 30, 60, 1))
                        update_if_changed(config.data.base, "checkbox_height", ui.Slider(_T("Height"), config.data.base.checkbox_height or 22, 16, 36, 1))
                        update_if_changed(config.data.base, "checkbox_knob_size", ui.Slider(_T("Knob Size"), config.data.base.checkbox_knob_size or 18, 10, 30, 1))
                        update_if_changed(config.data.base, "checkbox_knob_offset", ui.Slider(_T("Knob Offset"), config.data.base.checkbox_knob_offset or 2, 0, 6, 1))
                        update_if_changed(config.data.base, "checkbox_track_rounding", ui.Slider(_T("Track Rounding"), config.data.base.checkbox_track_rounding or 11, 0, 20, 1))
                        update_if_changed(config.data.base, "checkbox_knob_rounding", ui.Slider(_T("Knob Rounding"), config.data.base.checkbox_knob_rounding or 9, 0, 18, 1))
                    end)

                    ui.Group(_T("Toggle"), function()
                        update_if_changed(config.data.base, "toggle_width", ui.Slider(_T("Width") .. "##toggle", config.data.base.toggle_width or 40, 30, 60, 1))
                        update_if_changed(config.data.base, "toggle_height", ui.Slider(_T("Height") .. "##toggle", config.data.base.toggle_height or 22, 16, 36, 1))
                        update_if_changed(config.data.base, "toggle_knob_size", ui.Slider(_T("Knob Size") .. "##toggle", config.data.base.toggle_knob_size or 18, 10, 30, 1))
                        update_if_changed(config.data.base, "toggle_knob_offset", ui.Slider(_T("Knob Offset") .. "##toggle", config.data.base.toggle_knob_offset or 2, 0, 6, 1))
                        update_if_changed(config.data.base, "toggle_track_rounding", ui.Slider(_T("Track Rounding") .. "##toggle", config.data.base.toggle_track_rounding or 11, 0, 20, 1))
                        update_if_changed(config.data.base, "toggle_knob_rounding", ui.Slider(_T("Knob Rounding") .. "##toggle", config.data.base.toggle_knob_rounding or 9, 0, 18, 1))
                    end)

                    ui.Group(_T("Combo / Dropdown"), function()
                        update_if_changed(config.data.base, "combo_max_visible", ui.Slider(_T("Max Visible Items"), config.data.base.combo_max_visible or 5, 3, 10, 1))
                        update_if_changed(config.data.base, "combo_dropdown_gap", ui.Slider(_T("Dropdown Gap"), config.data.base.combo_dropdown_gap or 4, 0, 12, 1))
                        update_if_changed(config.data.base, "combo_thumb_min", ui.Slider(_T("Thumb Min Size") .. "##combo", config.data.base.combo_thumb_min or 20, 10, 40, 1))
                    end)

                    ui.Group(_T("Scroll & Animation"), function()
                        update_if_changed(config.data.base, "scroll_speed", ui.Slider(_T("Scroll Speed"), config.data.base.scroll_speed or 60, 20, 120, 5))
                        update_if_changed(config.data.base, "scroll_group_speed", ui.Slider(_T("Group Scroll Speed"), config.data.base.scroll_group_speed or 40, 10, 80, 5))
                        local anim_dur_display = math_floor((config.data.base.click_anim_duration or 0.25) * 100 + 0.5)
                        local new_anim_dur = ui.Slider(_T("Click Anim Duration (ms*10)"), anim_dur_display, 10, 50, 5)
                        update_if_changed(config.data.base, "click_anim_duration", new_anim_dur / 100)
                        update_if_changed(config.data.base, "click_anim_alpha", ui.Slider(_T("Click Anim Alpha"), config.data.base.click_anim_alpha or 40, 10, 100, 5))
                    end)
                end,
                function()
                    ui.Group(_T("Content Area"), function()
                        update_if_changed(config.data.base, "content_padding_y", ui.Slider(_T("Padding Y"), config.data.base.content_padding_y or 8, 0, 24, 1))
                        update_if_changed(config.data.base, "window_content_offset", ui.Slider(_T("Content Offset"), config.data.base.window_content_offset or 2, 0, 10, 1))
                        update_if_changed(config.data.base, "divider_width", ui.Slider(_T("Divider Width"), config.data.base.divider_width or 1, 0, 4, 1))
                        update_if_changed(config.data.base, "divider_padding", ui.Slider(_T("Divider Padding"), config.data.base.divider_padding or 8, 0, 20, 1))
                    end)

                    ui.Group(_T("Color Picker"), function()
                        update_if_changed(config.data.base, "color_preview_height", ui.Slider(_T("Preview Height"), config.data.base.color_preview_height or 12, 6, 24, 1))
                        update_if_changed(config.data.base, "color_preview_rounding", ui.Slider(_T("Preview Rounding"), config.data.base.color_preview_rounding or 4, 0, 12, 1))
                    end)

                    ui.Group(_T("Menu Hints"), function()
                        update_if_changed(config.data.base, "menu_hints_font_size", ui.Slider(_T("Font Size") .. "##menu_hints", config.data.base.menu_hints_font_size or 16, 10, 40, 1))
                        update_if_changed(config.data.base, "menu_hints_offset_y", ui.Slider(_T("Offset Y (below menu)"), config.data.base.menu_hints_offset_y or 2, 0, 20, 1))
                        update_if_changed(config.data.base, "menu_hints_height", ui.Slider(_T("Height") .. "##menu_hints", config.data.base.menu_hints_height or 30, 20, 60, 1))
                        update_if_changed(config.data.base, "menu_hints_padding", ui.Slider(_T("Padding") .. "##menu_hints", config.data.base.menu_hints_padding or 10, 4, 20, 1))
                        update_if_changed(config.data.base, "menu_hints_rounding", ui.Slider(_T("Rounding") .. "##menu_hints", config.data.base.menu_hints_rounding or 8, 0, 20, 1))
                    end)

                    ui.Group(_T("Inline Tab Bar"), function()
                        update_if_changed(config.data.base, "inline_tab_height", ui.Slider(_T("Height") .. "##inlinetab", config.data.base.inline_tab_height or 24, 16, 40, 1))
                        update_if_changed(config.data.base, "inline_tab_gap", ui.Slider(_T("Gap") .. "##inlinetab", config.data.base.inline_tab_gap or 4, 0, 16, 1))
                        update_if_changed(config.data.base, "inline_tab_indicator_height", ui.Slider(_T("Indicator Height"), config.data.base.inline_tab_indicator_height or 2, 1, 6, 1))
                    end)

                    ui.Group(_T("Separator"), function()
                        update_if_changed(config.data.base, "separator_height", ui.Slider(_T("Line Height") .. "##sep", config.data.base.separator_height or 1, 1, 4, 1))
                        update_if_changed(config.data.base, "separator_margin", ui.Slider(_T("Margin") .. "##sep", config.data.base.separator_margin or 8, 2, 20, 1))
                    end)

                    ui.Group(_T("Progress Bar"), function()
                        update_if_changed(config.data.base, "progress_height", ui.Slider(_T("Bar Height") .. "##progress", config.data.base.progress_height or 8, 4, 20, 1))
                        update_if_changed(config.data.base, "progress_rounding", ui.Slider(_T("Rounding") .. "##progress", config.data.base.progress_rounding or 4, 0, 12, 1))
                    end)

                    ui.Group(_T("Dual Column"), function()
                        update_if_changed(config.data.base, "dual_column_gap", ui.Slider(_T("Gap") .. "##dualcol", config.data.base.dual_column_gap or 8, 2, 20, 1))
                        update_if_changed(config.data.base, "dual_column_bottom_margin", ui.Slider(_T("Bottom Margin"), config.data.base.dual_column_bottom_margin or 10, 0, 30, 1))
                    end)

                    ui.Group(_T("Row Layout"), function()
                        update_if_changed(config.data.base, "row_gap", ui.Slider(_T("Row Gap"), config.data.base.row_gap or 8, 2, 20, 1))
                    end)
                end
            )
        end

    elseif state.subtab_idx == 3 then
        if not state.color_keys_window then rebuild_color_cache() end

        state.theme_subtab_idx = ui.SubTabBar2({
            _T("Manager"),
            _T("Window"),
            _T("Widget"),
            _T("Tab")
        }, state.theme_subtab_idx or 1)

        if state.theme_subtab_idx == 1 then
            ui.DualColumn(
                function()
                    ui.Group(_T("Theme Management"), function()
                        refresh_theme_list()

                        local new_theme_idx = ui.Combo(_T("Load Theme"), state.current_theme_idx, state.available_themes)
                        if new_theme_idx ~= state.current_theme_idx then
                            local theme_name = state.available_themes[new_theme_idx]
                            if config and config.load_theme then
                                local ok, result = pcall(config.load_theme, theme_name)
                                if ok and result ~= false then
                                    state.current_theme_idx = new_theme_idx
                                    rebuild_color_cache()
                                    if ui.force_update_scale then ui.force_update_scale() end
                                    if ui.update_colors then ui.update_colors() end
                                    if ui.refresh_background then ui.refresh_background() end
                                    if ui.clear_cache then ui.clear_cache() end
                                    if player_info and player_info.invalidate_color_cache then
                                        player_info.invalidate_color_cache()
                                    end
                                    refresh_image_list(true)
                                    refresh_theme_list(true)
                                    show_toast(_T("Theme loaded") .. ": " .. theme_name, "Success")
                                else
                                    show_toast(_T("Failed to load theme") .. ": " .. tostring(result), "Error")
                                end
                            end
                        end

                        local new_name = ui.TextInput(_T("Theme Name") .. "##save", state.new_theme_name, 32)
                        state.new_theme_name = new_name

                        if ui.Button(_T("Save Theme As")) then
                            if state.new_theme_name and #state.new_theme_name > 0 then
                                if config and config.save_as then
                                    local ok, result = pcall(config.save_as, state.new_theme_name)
                                    if ok and result ~= false then
                                        refresh_theme_list(true)
                                        show_toast(_T("Theme saved") .. ": " .. state.new_theme_name, "Success")
                                        state.new_theme_name = ""
                                    else
                                        show_toast(_T("Failed to save theme") .. ": " .. tostring(result), "Error")
                                    end
                                end
                            else
                                show_toast(_T("Please enter a theme name"), "Warning")
                            end
                        end

                        if ui.Button(_T("Refresh Theme List")) then
                            refresh_theme_list(true)
                            show_toast(_T("Theme list refreshed"), "Info")
                        end

                        if ui.Button(_T("Reset to Defaults")) then
                            local ok = false
                            if config and config.reset then
                                ok = pcall(config.reset)
                            end
                            if ok then
                                rebuild_color_cache()
                                if ui.force_update_scale then ui.force_update_scale() end
                                if ui.update_colors then ui.update_colors() end
                                if ui.refresh_background then ui.refresh_background() end
                                if ui.clear_cache then ui.clear_cache() end
                                if player_info and player_info.invalidate_color_cache then
                                    player_info.invalidate_color_cache()
                                end
                                refresh_image_list(true)
                                refresh_theme_list(true)
                                show_toast(_T("Reset to default theme"), "Warning")
                            else
                                show_toast(_T("Reset failed"), "Error")
                                if debugger then debugger.error("Config reset failed") end
                            end
                        end
                    end)
                end,
                function()
                end
            )

        elseif state.theme_subtab_idx == 2 then
            local function render_color_group(title, keys)
                if keys and #keys > 0 then
                    ui.Group(_T(title), function()
                        for _, key in ipairs(keys) do
                            ui.ColorPicker(_T(key), config.data.colors, key)
                        end
                    end)
                end
            end

            ui.DualColumn(
                function()
                    render_color_group("Window Colors", state.color_keys_window)
                end,
                function()
                    render_color_group("Group Colors", state.color_keys_group)
                end
            )

        elseif state.theme_subtab_idx == 3 then
            local function render_color_group(title, keys)
                if keys and #keys > 0 then
                    ui.Group(_T(title), function()
                        for _, key in ipairs(keys) do
                            ui.ColorPicker(_T(key), config.data.colors, key)
                        end
                    end)
                end
            end

            ui.DualColumn(
                function()
                    render_color_group("Checkbox Colors", state.color_keys_controls)
                    render_color_group("Slider Colors", state.color_keys_slider)
                    render_color_group("Combo Colors", state.color_keys_combo)
                end,
                function()
                    render_color_group("Scrollbar Colors", state.color_keys_scrollbar)
                    render_color_group("Inline Tab Colors", state.color_keys_inline)
                    render_color_group("Progress Colors", state.color_keys_progress)
                end
            )

        elseif state.theme_subtab_idx == 4 then
            local function render_color_group(title, keys)
                if keys and #keys > 0 then
                    ui.Group(_T(title), function()
                        for _, key in ipairs(keys) do
                            ui.ColorPicker(_T(key), config.data.colors, key)
                        end
                    end)
                end
            end

            ui.DualColumn(
                function()
                    render_color_group("Text Colors", state.color_keys_text)
                    render_color_group("Sidebar Tab Colors", state.color_keys_tab)
                    render_color_group("SubTab Colors", state.color_keys_subtab)
                end,
                function()
                    ui.Group(_T("Player Tags"), function()
                        if state.color_keys_tags then
                            for _, key in ipairs(state.color_keys_tags) do
                                ui.ColorPicker(_T(key), config.data.colors, key)
                            end
                        end
                    end)

                    render_color_group("Menu Hints Colors", state.color_keys_menu_hints)
                end
            )
        end

    elseif state.subtab_idx == 4 then
        state.icons_subtab_idx = ui.SubTabBar2({
            _T("Sidebar"),
            _T("Notification")
        }, state.icons_subtab_idx or 1)

        if state.icons_subtab_idx == 1 then
            ui.DualColumn(
                function()
                    ui.Group(_T("Sidebar Icons"), function()
                        local tab_names = {
                            _T("Self Icon"),
                            _T("Player Icon"),
                            _T("Online Icon"),
                            _T("Weapon Icon"),
                            _T("Spawn Icon"),
                            _T("Vehicle Icon"),
                            _T("World Icon"),
                            _T("Game Icon"),
                            _T("Heist Icon"),
                            _T("Setting Icon")
                        }

                        local icons = config.data.sidebar_icons
                        if not icons then icons = {}; config.data.sidebar_icons = icons end

                        for i, name in ipairs(tab_names) do
                            local current_val = icons[i] or "None"
                            local current_idx = 1
                            for idx, img in ipairs(state.bg_images) do
                                if img == current_val then
                                    current_idx = idx
                                    break
                                end
                            end

                            local new_idx = ui.Combo(name, current_idx, state.bg_images)

                            if new_idx ~= current_idx then
                                local selected = state.bg_images[new_idx]
                                icons[i] = selected
                                if ui.clear_cache then ui.clear_cache() end
                            end
                        end
                        for j = #tab_names + 1, #icons do icons[j] = nil end
                    end)
                end,
                function()
                    ui.Group(_T("Background Image"), function()
                        local is_enabled = config.data.bg_image_enabled
                        local new_enabled = ui.Checkbox(_T("Enable Background"), is_enabled)

                        if new_enabled ~= is_enabled then
                            config.data.bg_image_enabled = new_enabled
                            if ui.refresh_background then ui.refresh_background() end
                        end

                        if config.data.bg_image_enabled then
                            local new_idx = ui.Combo(_T("Image File"), state.bg_idx, state.bg_images)
                            if new_idx ~= state.bg_idx then
                                state.bg_idx = new_idx
                                local selected = state.bg_images[new_idx]

                                if selected == "None" then
                                    config.data.bg_image_file = ""
                                else
                                    config.data.bg_image_file = selected
                                end

                                if ui.refresh_background then ui.refresh_background() end
                            end

                            local opacity = config.data.bg_image_opacity or 255
                            local new_opacity = ui.Slider(_T("Opacity"), opacity, 0, 255, 1)
                            if new_opacity ~= opacity then
                                 config.data.bg_image_opacity = new_opacity
                            end

                            if ui.Button(_T("Reload Images List")) then
                                refresh_image_list(true)
                                show_toast(_T("Images refreshed"), "Success")
                            end

                            if #state.bg_images <= 1 then
                                ui.Button(_T("Put images in: ClickUl/Images/"))
                            end
                        end
                    end)

                    ui.Group(_T("Help & Info"), function()
                        ui.Button(_T("Formats: .png, .jpg, .gif"))

                        if ui.Button(_T("Copy Image Folder Path")) then
                            local full_path = get_clickui_dir() .. "Images\\"
                            local ok = false
                            if input_module and input_module.copy_to_clipboard then
                                ok = input_module.copy_to_clipboard(full_path)
                            end
                            if ok then
                                show_toast(_T("Copied to clipboard"), "Success")
                            else
                                show_toast(_T("Clipboard unavailable"), "Error")
                            end
                        end

                        ui.Button(_T("Tip: Click 'Reload' after adding files"))
                    end)
                end
            )

        elseif state.icons_subtab_idx == 2 then
            if not config.data.notification_icons then
                config.data.notification_icons = {}
            end
            local icons = config.data.notification_icons

            ui.DualColumn(
                function()
                    ui.Group(_T("Basic Notification Icons"), function()
                        local basic_notif_types = {
                            {key = "Success", label = _T("Success Icon")},
                            {key = "Warning", label = _T("Warning Icon")},
                            {key = "Error", label = _T("Error Icon")},
                            {key = "Info", label = _T("Info Icon")},
                            {key = "Spectator", label = _T("Spectator Icon")},
                            {key = "Modder", label = _T("Modder Detection Icon")}
                        }

                        for _, item in ipairs(basic_notif_types) do
                            local current_val = icons[item.key] or "logo.png"
                            local current_idx = 1
                            for idx, img in ipairs(state.bg_images) do
                                if img == current_val then
                                    current_idx = idx
                                    break
                                end
                            end

                            local new_idx = ui.Combo(item.label, current_idx, state.bg_images)

                            if new_idx ~= current_idx then
                                local selected = state.bg_images[new_idx]
                                icons[item.key] = selected
                                if ui.clear_cache then ui.clear_cache() end
                            end
                        end
                    end)
                end,
                function()
                    ui.Group(_T("Event Notification Icons"), function()
                        local event_notif_types = {
                            {key = "Join", label = _T("Player Join Icon")},
                            {key = "Leave", label = _T("Player Leave Icon")},
                            {key = "Script Event", label = _T("Script Event Icon")},
                            {key = "Network Event", label = _T("Network Event Icon")},
                            {key = "Protection", label = _T("Protection Icon")},
                            {key = "Player Manager", label = _T("Player Manager Icon")}
                        }

                        for _, item in ipairs(event_notif_types) do
                            local current_val = icons[item.key] or "logo.png"
                            local current_idx = 1
                            for idx, img in ipairs(state.bg_images) do
                                if img == current_val then
                                    current_idx = idx
                                    break
                                end
                            end

                            local new_idx = ui.Combo(item.label, current_idx, state.bg_images)

                            if new_idx ~= current_idx then
                                local selected = state.bg_images[new_idx]
                                icons[item.key] = selected
                                if ui.clear_cache then ui.clear_cache() end
                            end
                        end
                    end)
                end
            )
        end

    elseif state.subtab_idx == 5 then
        if not state.color_keys_notify_left then rebuild_color_cache() end

        state.notify_subtab_idx = ui.SubTabBar2({
            _T("Colors"),
            _T("Style & Animation"),
            _T("Layout")
        }, state.notify_subtab_idx or 1)

        if state.notify_subtab_idx == 1 then
            ui.DualColumn(
                function()
                    ui.Group(_T("Notification Colors"), function()
                        ui.ColorPicker(_T("Notification Info"), config.data.colors, "Notification Background")
                        if state.color_keys_notify_right then
                            for _, key in ipairs(state.color_keys_notify_right) do
                                ui.ColorPicker(_T(key), config.data.colors, key)
                            end
                        end
                    end)

                    ui.Group(_T("Flash Effect"), function()
                        ui.ColorPicker(_T("Notification Flash"), config.data.colors, "Notification Flash")
                    end)
                end,
                function()
                    ui.Group(_T("Online Notification Colors"), function()
                        ui.ColorPicker(_T("Player Join"), config.data.colors, "Notification Join")
                        ui.ColorPicker(_T("Player Leave"), config.data.colors, "Notification Leave")
                        ui.ColorPicker(_T("Spectator Detection"), config.data.colors, "Notification Spectator")
                        ui.ColorPicker(_T("Modder Detection"), config.data.colors, "Notification Modder")
                        ui.ColorPicker(_T("Script Event"), config.data.colors, "Notification Script Event")
                        ui.ColorPicker(_T("Network Event"), config.data.colors, "Notification Network Event")
                        ui.ColorPicker(_T("Protection"), config.data.colors, "Notification Protection")
                        ui.ColorPicker(_T("Player Manager"), config.data.colors, "Notification Player Manager")
                    end)
                end
            )

        elseif state.notify_subtab_idx == 2 then
            ui.DualColumn(
                function()
                    ui.Group(_T("Notification Style"), function()
                        if not config.data.base.notif_radius then config.data.base.notif_radius = 8 end
                        if not config.data.base.notif_title_size then config.data.base.notif_title_size = 17 end
                        if not config.data.base.notif_message_size then config.data.base.notif_message_size = 14 end
                        if not config.data.base.notif_spacing then config.data.base.notif_spacing = 8 end
                        if not config.data.base.notif_margin_x then config.data.base.notif_margin_x = 20 end
                        if not config.data.base.notif_margin_y then config.data.base.notif_margin_y = 20 end
                        if not config.data.base.notif_max_count then config.data.base.notif_max_count = 12 end
                        if not config.data.base.notif_width then config.data.base.notif_width = 320 end
                        if not config.data.base.notif_padding then config.data.base.notif_padding = 6 end
                        if not config.data.base.notif_icon_size then config.data.base.notif_icon_size = 32 end
                        if not config.data.base.notif_min_height then config.data.base.notif_min_height = 60 end
                        if not config.data.base.notif_duration then config.data.base.notif_duration = 5.0 end
                        if not config.data.base.notif_anim_speed_in then config.data.base.notif_anim_speed_in = 4.0 end
                        if not config.data.base.notif_anim_stack_speed then config.data.base.notif_anim_stack_speed = 15.0 end
                        if not config.data.base.notif_flash_cooldown then config.data.base.notif_flash_cooldown = 1.5 end

                        update_if_changed(config.data.base, "notif_radius", ui.Slider(_T("Corner Radius") .. "##notif", config.data.base.notif_radius, 0, 20, 1))
                        update_if_changed(config.data.base, "notif_title_size", ui.Slider(_T("Title Font Size"), config.data.base.notif_title_size, 12, 24, 1))
                        update_if_changed(config.data.base, "notif_message_size", ui.Slider(_T("Message Font Size"), config.data.base.notif_message_size, 10, 20, 1))
                        update_if_changed(config.data.base, "notif_spacing", ui.Slider(_T("Spacing Between"), config.data.base.notif_spacing, 0, 30, 1))
                        update_if_changed(config.data.base, "notif_margin_x", ui.Slider(_T("Screen Margin X"), config.data.base.notif_margin_x, 0, 200, 5))
                        update_if_changed(config.data.base, "notif_margin_y", ui.Slider(_T("Screen Margin Y"), config.data.base.notif_margin_y, 0, 200, 5))
                        update_if_changed(config.data.base, "notif_max_count", ui.Slider(_T("Max Count"), config.data.base.notif_max_count, 1, 30, 1))
                        update_if_changed(config.data.base, "notif_width", ui.Slider(_T("Width"), config.data.base.notif_width, 200, 600, 10))
                        update_if_changed(config.data.base, "notif_padding", ui.Slider(_T("Inner Padding"), config.data.base.notif_padding, 0, 30, 1))
                        update_if_changed(config.data.base, "notif_icon_size", ui.Slider(_T("Icon Size"), config.data.base.notif_icon_size, 0, 64, 1))
                        update_if_changed(config.data.base, "notif_min_height", ui.Slider(_T("Min Height (No Icon)"), config.data.base.notif_min_height, 0, 200, 5))
                        update_if_changed(config.data.base, "notif_duration", ui.Slider(_T("Duration (s)"), config.data.base.notif_duration, 0.5, 15.0, 0.5))
                        update_if_changed(config.data.base, "notif_anim_speed_in", ui.Slider(_T("Anim Speed In"), config.data.base.notif_anim_speed_in, 1.0, 30.0, 0.5))
                        update_if_changed(config.data.base, "notif_anim_stack_speed", ui.Slider(_T("Anim Stack Speed"), config.data.base.notif_anim_stack_speed, 1.0, 30.0, 0.5))
                        update_if_changed(config.data.base, "notif_flash_cooldown", ui.Slider(_T("Flash Cooldown (s)"), config.data.base.notif_flash_cooldown, 0.0, 5.0, 0.1))
                    end)
                end,
                function()
                    ui.Group(_T("Notification Time Bar"), function()
                        if config.data.base.notif_time_bar_enabled == nil then config.data.base.notif_time_bar_enabled = true end
                        if not config.data.base.notif_time_bar_height then config.data.base.notif_time_bar_height = 2 end
                        if not config.data.base.notif_time_bar_opacity then config.data.base.notif_time_bar_opacity = 180 end

                        local old_enabled = config.data.base.notif_time_bar_enabled
                        local new_enabled = ui.Checkbox(_T("Enable Time Bar"), old_enabled)
                        if new_enabled ~= old_enabled then
                            config.data.base.notif_time_bar_enabled = new_enabled
                        end
                        update_if_changed(config.data.base, "notif_time_bar_height", ui.Slider(_T("Bar Height (px)"), config.data.base.notif_time_bar_height, 1, 8, 1))
                        update_if_changed(config.data.base, "notif_time_bar_opacity", ui.Slider(_T("Bar Opacity"), config.data.base.notif_time_bar_opacity, 0, 255, 5))
                    end)

                    ui.Group(_T("Animation Enhancements"), function()
                        if not config.data.base.notif_exit_speed_multiplier then
                            config.data.base.notif_exit_speed_multiplier = 1.5
                        end
                        if not config.data.base.notif_flash_decay_speed then
                            config.data.base.notif_flash_decay_speed = 6.0
                        end

                        update_if_changed(config.data.base, "notif_exit_speed_multiplier", ui.Slider(
                            _T("Exit Speed Multiplier"),
                            config.data.base.notif_exit_speed_multiplier,
                            1.0, 3.0, 0.1
                        ))

                        update_if_changed(config.data.base, "notif_flash_decay_speed", ui.Slider(
                            _T("Flash Decay Speed"),
                            config.data.base.notif_flash_decay_speed,
                            1.0, 20.0, 0.5
                        ))
                    end)
                end
            )

        elseif state.notify_subtab_idx == 3 then
            ui.DualColumn(
                function()
                    ui.Group(_T("Notification Position"), function()
                        local position_options = {_T("Bottom Right"), _T("Bottom Left"), _T("Top Right"), _T("Top Left")}
                        local position_values = {"bottom_right", "bottom_left", "top_right", "top_left"}

                        local current_position = config.data.notification_position or "bottom_right"
                        local current_idx = 1
                        for i, val in ipairs(position_values) do
                            if val == current_position then
                                current_idx = i
                                break
                            end
                        end

                        local new_idx = ui.Combo(_T("Position"), current_idx, position_options)

                        if new_idx ~= current_idx then
                            config.data.notification_position = position_values[new_idx]
                            show_toast(_T("Notification position changed to") .. " " .. position_options[new_idx], "Info")
                        end
                    end)
                end,
                function()
                    ui.Group(_T("Test Notifications"), function()
                        if ui.Button(_T("Test All Notifications")) then
                            show_toast(_T("Success notification"), "Success")
                            show_toast(_T("Warning notification"), "Warning")
                            show_toast(_T("Error notification"), "Error")
                            show_toast(_T("Info notification"), "Info")
                            show_toast(_T("Player is joined"), "Join")
                            show_toast(_T("Player is left"), "Leave")
                            show_toast(_T("Spectator Detected"), "Spectator")
                            show_toast(_T("Modder Detected"), "Modder Detection")
                            show_toast(_T("Script Event Blocked"), "Script Event")
                            show_toast(_T("Network Event Blocked"), "Network Event")
                            show_toast(_T("Protection Triggered"), "Protection")
                            show_toast(_T("Player Manager Action"), "Player Manager")
                        end

                        if ui.Button(_T("Test Long Notification")) then
                            show_toast(_T("This is a very long notification message to test text wrapping. The notification system should automatically wrap this text to multiple lines and adjust the background height accordingly."), "Info")
                        end
                    end)
                end
            )
        end

    elseif state.subtab_idx == 6 then
        if not state.color_keys_overlay then rebuild_color_cache() end

        ui.DualColumn(
            function()
                ui.Group(_T("Overlay Colors"), function()
                    if state.color_keys_overlay and #state.color_keys_overlay > 0 then
                        for _, key in ipairs(state.color_keys_overlay) do
                            local old_color = config.data.colors[key]
                            if old_color then
                                local old_r, old_g, old_b, old_a = old_color.r, old_color.g, old_color.b, old_color.a
                                ui.ColorPicker(_T(key), config.data.colors, key)
                                local new_color = config.data.colors[key]
                                if new_color and (new_color.r ~= old_r or new_color.g ~= old_g or new_color.b ~= old_b or new_color.a ~= old_a) then
                                    if player_info and player_info.invalidate_color_cache then
                                        player_info.invalidate_color_cache()
                                    end
                                end
                            else
                                ui.ColorPicker(_T(key), config.data.colors, key)
                            end
                        end
                    else
                        ui.Button(_T("No Overlay colors found"))
                    end
                end)
            end,
            function()
                ui.Group(_T("Layout Settings"), function()
                    if not config.data.base.overlay_font_size then config.data.base.overlay_font_size = 14 end
                    if not config.data.base.overlay_radius then config.data.base.overlay_radius = 4 end
                    if not config.data.base.overlay_offset_x then config.data.base.overlay_offset_x = 10 end

                    local old_font = config.data.base.overlay_font_size
                    local old_radius = config.data.base.overlay_radius
                    local old_offset_x = config.data.base.overlay_offset_x

                    config.data.base.overlay_font_size = ui.Slider(_T("Font Size"), config.data.base.overlay_font_size, 10, 24, 1)
                    config.data.base.overlay_radius = ui.Slider(_T("Corner Radius") .. "##overlay", config.data.base.overlay_radius, 0, 20, 1)
                    config.data.base.overlay_offset_x = ui.Slider(_T("Horizontal Offset"), config.data.base.overlay_offset_x, -50, 200, 5)

                    if old_font ~= config.data.base.overlay_font_size or old_radius ~= config.data.base.overlay_radius or old_offset_x ~= config.data.base.overlay_offset_x then
                        local now = os_clock()
                        if now - state.last_save_time >= state.save_cooldown then
                            if config.save then config.save() end
                            state.last_save_time = now
                        end
                    end
                end)
            end
        )

    elseif state.subtab_idx == 7 then
        ui.DualColumn(
            function()
                ui.Group(_T("Debug System"), function()
                    local debug_sys = _G.debug_sys
                    if debug_sys then
                        local cfg = debug_sys.get_config()

                        local new_enabled = ui.Checkbox(_T("Enable Debug System"), cfg.enabled)
                        if new_enabled ~= cfg.enabled then
                            if new_enabled then
                                debug_sys.enable()
                                show_toast(_T("Debug system enabled"), "Success")
                                if debugger then debugger.info("Debug system enabled by user") end
                            else
                                debug_sys.disable()
                                show_toast(_T("Debug system disabled"), "Info")
                            end
                            sync_debug_settings()
                        end

                        if cfg.enabled then
                            local level_names = {_T("DEBUG"), _T("INFO"), _T("WARN"), _T("ERROR")}
                            local current_level_idx = cfg.log_level
                            local new_level_idx = ui.Combo(_T("Log Level"), current_level_idx, level_names)
                            if new_level_idx ~= current_level_idx then
                                debug_sys.set_level(new_level_idx)
                                show_toast(string.format(_T("Log level: %s"), level_names[new_level_idx]), "Info")
                                if debugger then debugger.info("Log level changed", {level = level_names[new_level_idx]}) end
                                sync_debug_settings()
                            end

                            local new_log_to_file = ui.Checkbox(_T("Log to File"), cfg.log_to_file)
                            if new_log_to_file ~= cfg.log_to_file then
                                if debug_sys.set_log_to_file then
                                    debug_sys.set_log_to_file(new_log_to_file)
                                else
                                    cfg.log_to_file = new_log_to_file
                                end
                                sync_debug_settings()
                            end

                            local new_print_console = ui.Checkbox(_T("Print to Console"), cfg.print_to_console)
                            if new_print_console ~= cfg.print_to_console then
                                cfg.print_to_console = new_print_console
                                sync_debug_settings()
                            end

                            local current_filter = cfg.module_filter or ""
                            local new_filter = ui.TextInput(_T("Module Filter") .. "##debug", current_filter, 32)
                            if new_filter ~= current_filter then
                                if debug_sys.set_module_filter then
                                    debug_sys.set_module_filter(new_filter)
                                else
                                    cfg.module_filter = new_filter
                                end
                                sync_debug_settings()
                            end
                        end
                    else
                        ui.Button(_T("Debug system not available"))
                    end
                end)
            end,
            function()
                local debug_sys = _G.debug_sys
                if debug_sys then
                    local cfg = debug_sys.get_config()

                    if cfg.enabled then
                        ui.Group(_T("Display Options"), function()
                            local new_timestamp = ui.Checkbox(_T("Show Timestamp"), cfg.show_timestamp)
                            if new_timestamp ~= cfg.show_timestamp then
                                cfg.show_timestamp = new_timestamp
                                sync_debug_settings()
                            end

                            local new_memory = ui.Checkbox(_T("Show Memory Usage"), cfg.show_memory)
                            if new_memory ~= cfg.show_memory then
                                cfg.show_memory = new_memory
                                sync_debug_settings()
                            end

                            local new_perf = ui.Checkbox(_T("Show Performance"), cfg.show_performance)
                            if new_perf ~= cfg.show_performance then
                                cfg.show_performance = new_perf
                                sync_debug_settings()
                            end
                        end)

                        ui.Group(_T("Utilities"), function()
                            if ui.Button(_T("Clear Debug History")) then
                                local count = debug_sys.clear_history()
                                show_toast(string.format(_T("Cleared %d log entries"), count or 0), "Success")
                            end

                            if ui.Button(_T("Dump History to File")) then
                                local count = debug_sys.get_history_count and debug_sys.get_history_count() or 0
                                if count > 0 then
                                    debug_sys.dump_history()
                                    local log_path = debug_sys.get_log_file_path and debug_sys.get_log_file_path() or "ClickUl/logs/"
                                    show_toast(string.format(_T("Wrote %d entries to: %s"), count, log_path), "Success")
                                else
                                    show_toast(_T("No log history to dump (history is empty)"), "Warning")
                                end
                            end

                            if ui.Button(_T("Show Current Memory")) then
                                local mem = debug_sys.get_memory and debug_sys.get_memory()
                                if mem then
                                    show_toast(string.format("Memory: %.2f MB (%.0f KB)", mem.mb, mem.kb), "Info")
                                else
                                    show_toast(_T("Memory info unavailable"), "Error")
                                end
                            end

                            if ui.Button(_T("Force Garbage Collection")) then
                                local before = debug_sys.get_memory and debug_sys.get_memory()
                                debug_sys.force_gc()
                                local after = debug_sys.get_memory and debug_sys.get_memory()
                                if before and after then
                                    local freed = before.kb - after.kb
                                    show_toast(string.format("GC: %.0f KB freed (%.2f MB -> %.2f MB)", freed, before.mb, after.mb), "Success")
                                else
                                    show_toast(_T("GC executed"), "Success")
                                end
                            end
                        end)
                    end
                end
            end
        )
    end
end

return module
